import { useEnv } from '@/hooks/core/useEnv';
import { isArray, isReqUrl } from '@/utils/is';
import { ref, unref } from 'vue';
import type { dataItem } from '../types';

interface DataItem {
  src: string;
  localPath?: string;
}

export interface UsePinterestOptions {
  imgInitWidth: number;
  data?: DataItem[];
}

export function usePinterest(op: UsePinterestOptions) {
  const { windowWidth } = uni.getWindowInfo()

  const imgInitWidth = ref(op.imgInitWidth);

  /** 间距 */
  const space = ref(15);
  /** 列数 */
  const columns = ref(1);
  /** 图片宽度 */
  const imgWidth = ref(0);
  /** 列高 */
  const allColHeight = ref<number[]>([0]);
  /** 外层容器高度 */
  const containerHeight = ref(500);
  /** 渲染的数据列表 */
  const dataList = ref<dataItem[]>([]);

  /** 根据图片宽度计算 列数 间隙 */
  function getCol(width?: number) {
    const imgW = uni.upx2px(width || imgInitWidth.value);
    const col = Math.floor(windowWidth / imgW);
    const sp = (windowWidth - col * imgW) / (col + 1);
    space.value = sp;
    columns.value = col;
    imgWidth.value = imgW;
    allColHeight.value = new Array(col);
    allColHeight.value.fill(0);
  }

  function getStyles(practicalImgWidth: number, practicalImgHeight: number) {
    const nextTops = allColHeight.value;
    const w = imgWidth.value;
    const h = (practicalImgHeight * w) / practicalImgWidth;
    let styles = {
      top: '0px',
      left: '0px',
      width: w + 'px',
      height: h + 'px',
    };
    let minTop = Math.min.apply(null, nextTops);
    styles.top = minTop + space.value + 'px';
    let index = nextTops.indexOf(minTop);
    allColHeight.value[index] += h + space.value;
    let left = (index + 1) * space.value + index * w;
    styles.left = left + 'px';
    return styles;
  }

  function setContainerHeight() {
    containerHeight.value = Math.max.apply(null, allColHeight.value);
  }

  function __init() {
    op.data && setData(op.data);
    setImgWidth(imgInitWidth.value);
  }

  __init();

  async function setData(data?: DataItem[]) {
    if (!isArray(data)) throw 'urls is not Array<string>';
    for (let index = 0; index < data.length; index++) {
      const v = data[index];
      await setItem(v.src, v.localPath);
    }
    setContainerHeight();
  }

  /**
   * @description 设置item
   * @date 20/09/2022
   * @param {string} src
   * @param {string} [localPath] 本地图片路径
   */
  async function setItem(src: string, localPath?: string) {
    let url = src;
    if (!localPath) {
      const { getEnv } = useEnv();
      const compressRate = getEnv('CDN_IMG_COMPRESSRATE');
      if (isReqUrl(url) && !url.includes('?')) {
        url += compressRate;
      }
    }

    try {
      const { width, height, path } = await wx.getImageInfo({ src: localPath || url });
      dataList.value.push({
        imagePathSmall: path,
        imagePathBig: src,
        imgWidth: width,
        imgHeight: height,
        styles: getStyles(width, height),
      });
    } catch (error) {
      dataList.value.push({
        imagePathSmall: localPath || url,
        imagePathBig: src,
        imgWidth: imgWidth.value,
        imgHeight: imgWidth.value,
        styles: getStyles(imgWidth.value, imgWidth.value),
      });
      console.log(error)
      console.log('图片加载失败', url);
    }
  }

  function setImgWidth(width: number) {
    imgInitWidth.value = width;
    getCol(width);
    dataList.value.forEach((v) => {
      v.styles = getStyles(v.imgWidth, v.imgHeight);
    });
    setContainerHeight();
  }

  /**
   * @description 删除item
   * @date 20/09/2022
   * @param {number} index
   */
  function delItem(index: number) {
    dataList.value.splice(index, 1);
    setImgWidth(imgInitWidth.value);
  }

  /**
   * @description 置顶
   * @date 20/09/2022
   * @param {number} index
   */
  function setTop(index: number) {
    const arr = unref(dataList);
    let a2 = arr[index];
    dataList.value.splice(index, 1);
    dataList.value.unshift(a2);
    setImgWidth(imgInitWidth.value);
  }

  return {
    dataList,
    containerHeight,
    setData,
    delItem,
    setImgWidth,
    setTop,
  };
}
